package com.turman.plyopengl

import android.content.Context
import android.opengl.GLES20
import android.opengl.GLSurfaceView
import android.opengl.Matrix
import com.turman.plyopengl.objects.PlyObject
import com.turman.plyopengl.programs.PlyShaderProgram
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

class DrawPlyRenderer(private val context: Context) : GLSurfaceView.Renderer {

    private var rotateAngleX = 0f
    private var rotateAngleY = 0f
    private var rotateAngleZ = 0f
    private var translateX = 0f
    private var translateY = 0f
    private var translateZ = 0f


    /**
     * 透视投影矩阵
     */
    private val projectionMatrix: FloatArray = FloatArray(16)

    /**
     * 模型矩阵
     */
    private val modelMatrix = FloatArray(16)

    private val viewMatrix = FloatArray(16)
    private val viewProjectionMatrix = FloatArray(16)
    private val modelViewProjectionMatrix = FloatArray(16)

    private lateinit var plyObject: PlyObject
    private lateinit var plyShaderProgram: PlyShaderProgram

    fun translate(t1:Float,t2:Float,scale:Float){
        if (verticesRange!=null) {
            val translateScaleFactor = 10 / 200f

            val xRange = (verticesRange?.get(0)?:0f) - (verticesRange?.get(1)?:0f)
            val yRange = (verticesRange?.get(0)?:0f) - (verticesRange?.get(1)?:0f)
            val zRange = (verticesRange?.get(0)?:0f) - (verticesRange?.get(1)?:0f)

            if (xRange<yRange && xRange<zRange) {
                translateY += t1 * translateScaleFactor
                translateZ += t2 * translateScaleFactor

                translateX += scale* translateScaleFactor
            } else if (yRange<zRange) {
                translateX += t1 * translateScaleFactor
                translateZ += t2 * translateScaleFactor

                translateY += scale* translateScaleFactor
            } else {
                translateX += t1 * translateScaleFactor
                translateY += t2 * translateScaleFactor

                translateZ += scale* translateScaleFactor
            }
            updateViewMatrix()
        }
    }

    fun drawRect(sx:Float,sy:Float,ex:Float,ey:Float) {

    }

    private fun updateViewMatrix() {
        if (verticesRange!=null) {
            val xRange = (verticesRange?.get(0)?:0f) - (verticesRange?.get(1)?:0f)
            val yRange = (verticesRange?.get(0)?:0f) - (verticesRange?.get(1)?:0f)
            val zRange = (verticesRange?.get(0)?:0f) - (verticesRange?.get(1)?:0f)

            if (xRange<yRange && xRange<zRange) {
                Matrix.setLookAtM(viewMatrix, 0, (verticesRange?.get(0)?:0f)-2f + translateX, 0f, 0f, 0f, 0f, 0f, 0f, 1.0f, 0.0f)
                Matrix.rotateM(viewMatrix, 0, rotateAngleX, 1f, 0f, 0f)
                Matrix.translateM(viewMatrix, 0, 0f, -translateY, -translateZ)
            } else if (yRange<zRange) {
                Matrix.setLookAtM(viewMatrix, 0, 0f, (verticesRange?.get(2)?:0f)-2f + translateY, 0f, 0f, 0f, 0f, 1f, 0f, 0.0f)
                Matrix.rotateM(viewMatrix, 0, rotateAngleY, 0f, 1f, 0f)
                Matrix.translateM(viewMatrix, 0, -translateX, 0f, -translateZ)
            } else {
                Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, (verticesRange?.get(4)?:0f)-2f + translateZ, 0f, 0f, 0f, 0f, 1f, 0.0f)
                Matrix.rotateM(viewMatrix, 0, rotateAngleZ, 0f, 0f, 1f)
                Matrix.translateM(viewMatrix, 0, -translateX, -translateY, 0f)
            }
        }
    }

    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        // 设置Clear颜色
        GLES20.glClearColor(0F, 0F, 0F, 0F)

        plyObject = PlyObject(context.assets.open("3.ply"))
        plyShaderProgram = PlyShaderProgram(context)
    }

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        GLES20.glViewport(0, 0, width, height)
        //创建投影矩阵
        MatrixHelper.prespectiveM(
            projectionMatrix,
            55f,
            width.toFloat() / height.toFloat(),
            -10f,
            10f
        )

        //将模型矩阵设置为欸单位矩阵，然后沿着z轴平移量-2.5。
        Matrix.setIdentityM(modelMatrix, 0)
        //平移
        Matrix.translateM(modelMatrix, 0, 0f, 0f, -8f)
        //旋转,绕x轴旋转60
//        Matrix.rotateM(modelMatrix, 0, -60f, 1f, 0f, 0f)

        //将模型矩阵和投影矩阵相乘获得最终的变换矩阵
        val temp = FloatArray(16)
        Matrix.multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0)
        System.arraycopy(temp, 0, projectionMatrix, 0, temp.size)

        updateViewMatrix()
    }

    override fun onDrawFrame(gl: GL10?) {
        // 清除之前绘制的内容
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
        //这里将viewmatrix视图矩阵添加到绘制计算，使得场景中的物体随着视角（摄像头）的方向变化而旋转位移
        Matrix.multiplyMM(viewProjectionMatrix, 0, projectionMatrix, 0, viewMatrix, 0)

//        positionTableInScene()
        plyShaderProgram.useProgram()
        plyShaderProgram.setUniforms(viewProjectionMatrix)
        plyObject.bindData(plyShaderProgram)
        plyObject.draw()
    }

    private fun positionTableInScene() {
        Matrix.setIdentityM(modelMatrix, 0)
        Matrix.rotateM(modelMatrix, 0, -90f, 1f, 0f, 0f)
        Matrix.multiplyMM(
            modelViewProjectionMatrix, 0, viewProjectionMatrix,
            0, modelMatrix, 0
        )
    }

    private fun positionObjectInScene(x: Float, y: Float, z: Float) {
        Matrix.setIdentityM(modelMatrix, 0)
        Matrix.translateM(modelMatrix, 0, x, y, z)
        Matrix.multiplyMM(
            modelViewProjectionMatrix, 0, viewProjectionMatrix,
            0, modelMatrix, 0
        )
    }

}